
extern "C" {
    pub type _IO_wide_data;
    pub type _IO_codecvt;
    pub type _IO_marker;
    fn fclose(__stream: *mut FILE) -> i32;
    fn fopen(_: *const i8, _: *const i8) -> *mut FILE;
    fn printf(_: *const i8, _: ...) -> i32;
    fn perror(__s: *const i8);
    fn feof(__stream: *mut FILE) -> i32;
    fn fseek(__stream: *mut FILE, __off: i64, __whence: i32) -> i32;
    fn fgets(__s: *mut i8, __n: i32, __stream: *mut FILE) -> *mut i8;
    fn atof(__nptr: *const i8) -> f64;
    fn srand(__seed: u32);
    fn malloc(_: u64) -> *mut ();
    fn free(_: *mut ());
    fn exit(_: i32) -> !;
    fn time(__timer: *mut time_t) -> time_t;
    fn strcmp(_: *const i8, _: *const i8) -> i32;
    fn strtok(_: *mut i8, _: *const i8) -> *mut i8;
    fn strlen(_: *const i8) -> u64;
    fn genann_init(inputs: i32, hidden_layers: i32, hidden: i32, outputs: i32) -> *mut genann;
    fn genann_free(ann: *mut genann);
    fn genann_run(ann: *const genann, inputs: *const f64) -> *const f64;
    fn genann_train(
        ann: *const genann,
        inputs: *const f64,
        desired_outputs: *const f64,
        learning_rate: f64,
    );
}
pub type size_t = u64;
pub type __off_t = i64;
pub type __off64_t = i64;
pub type __time_t = i64;
#[derive(Copy, Clone)]
#[repr(C)]
pub struct _IO_FILE {
    pub _flags: i32,
    pub _IO_read_ptr: *mut i8,
    pub _IO_read_end: *mut i8,
    pub _IO_read_base: *mut i8,
    pub _IO_write_base: *mut i8,
    pub _IO_write_ptr: *mut i8,
    pub _IO_write_end: *mut i8,
    pub _IO_buf_base: *mut i8,
    pub _IO_buf_end: *mut i8,
    pub _IO_save_base: *mut i8,
    pub _IO_backup_base: *mut i8,
    pub _IO_save_end: *mut i8,
    pub _markers: *mut _IO_marker,
    pub _chain: *mut _IO_FILE,
    pub _fileno: i32,
    pub _flags2: i32,
    pub _old_offset: __off_t,
    pub _cur_column: u16,
    pub _vtable_offset: i8,
    pub _shortbuf: [i8; 1],
    pub _lock: *mut (),
    pub _offset: __off64_t,
    pub _codecvt: *mut _IO_codecvt,
    pub _wide_data: *mut _IO_wide_data,
    pub _freeres_list: *mut _IO_FILE,
    pub _freeres_buf: *mut (),
    pub __pad5: size_t,
    pub _mode: i32,
    pub _unused2: [i8; 20],
}
pub type _IO_lock_t = ();
pub type FILE = _IO_FILE;
pub type time_t = __time_t;
#[derive(Copy, Clone)]
#[repr(C)]
pub struct genann {
    pub inputs: i32,
    pub hidden_layers: i32,
    pub hidden: i32,
    pub outputs: i32,
    pub activation_hidden: genann_actfun,
    pub activation_output: genann_actfun,
    pub total_weights: i32,
    pub total_neurons: i32,
    pub weight: *mut f64,
    pub output: *mut f64,
    pub delta: *mut f64,
}
pub type genann_actfun = Option<unsafe extern "C" fn(*const genann, f64) -> f64>;
#[no_mangle]
pub static mut iris_data: *const i8 = b"example/iris.data\0" as *const u8 as *const i8;
#[no_mangle]
pub static mut input: *mut f64 = 0 as *const f64 as *mut f64;
#[no_mangle]
pub static mut class: *mut f64 = 0 as *const f64 as *mut f64;
#[no_mangle]
pub static mut samples: i32 = 0;
#[no_mangle]
pub static mut class_names: [*const i8; 3] = [
    b"Iris-setosa\0" as *const u8 as *const i8,
    b"Iris-versicolor\0" as *const u8 as *const i8,
    b"Iris-virginica\0" as *const u8 as *const i8,
];
#[no_mangle]
pub extern "C" fn load_data() {
    let mut in_0: *mut FILE = unsafe {
        fopen(
            b"example/iris.data\0" as *const u8 as *const i8,
            b"r\0" as *const u8 as *const i8,
        )
    };
    if in_0.is_null() {
        (unsafe {
            printf(
                b"Could not open file: %s\n\0" as *const u8 as *const i8,
                iris_data,
            )
        });
        (unsafe { exit(1 as i32) });
    }
    let mut line: [i8; 1024] = [0; 1024];
    while (unsafe { feof(in_0) }) == 0
        && !(unsafe { fgets(line.as_mut_ptr(), 1024, in_0) }).is_null()
    {
        (unsafe { samples += 1 });
    }
    (unsafe { fseek(in_0, 0 as i64, 0) });
    (unsafe {
        printf(
            b"Loading %d data points from %s\n\0" as *const u8 as *const i8,
            samples,
            iris_data,
        )
    });
    (unsafe {
        input = malloc(
            (::core::mem::size_of::<f64>() as u64)
                .wrapping_mul(samples as u64)
                .wrapping_mul(4 as i32 as u64),
        ) as *mut f64
    });
    (unsafe {
        class = malloc(
            (::core::mem::size_of::<f64>() as u64)
                .wrapping_mul(samples as u64)
                .wrapping_mul(3 as i32 as u64),
        ) as *mut f64
    });
    let mut i: i32 = 0;
    let mut j: i32 = 0;
    i = 0;
    while i < (unsafe { samples }) {
        let mut p: *mut f64 = unsafe { input.offset((i * 4) as isize) };
        let mut c: *mut f64 = unsafe { class.offset((i * 3) as isize) };
        let fresh0 = unsafe { &mut (*c.offset(2 as i32 as isize)) };
        *fresh0 = 0.0f64;
        let fresh1 = unsafe { &mut (*c.offset(1 as i32 as isize)) };
        *fresh1 = *fresh0;
        (unsafe { *c.offset(0 as i32 as isize) = *fresh1 });
        if (unsafe { fgets(line.as_mut_ptr(), 1024, in_0) }).is_null() {
            (unsafe { perror(b"fgets\0" as *const u8 as *const i8) });
            (unsafe { exit(1 as i32) });
        }
        let mut split: *mut i8 =
            unsafe { strtok(line.as_mut_ptr(), b",\0" as *const u8 as *const i8) };
        j = 0;
        while j < 4 {
            (unsafe { *p.offset(j as isize) = atof(split) });
            split = unsafe { strtok(std::ptr::null_mut::<i8>(), b",\0" as *const u8 as *const i8) };
            j += 1;
        }
        (unsafe {
            *split.offset((strlen(split)).wrapping_sub(1 as i32 as u64) as isize) = 0 as i8
        });
        if (unsafe { strcmp(split, class_names[0 as i32 as usize]) }) == 0 {
            (unsafe { *c.offset(0 as i32 as isize) = 1.0f64 });
        } else if (unsafe { strcmp(split, class_names[1 as i32 as usize]) }) == 0 {
            (unsafe { *c.offset(1 as i32 as isize) = 1.0f64 });
        } else if (unsafe { strcmp(split, class_names[2 as i32 as usize]) }) == 0 {
            (unsafe { *c.offset(2 as i32 as isize) = 1.0f64 });
        } else {
            (unsafe { printf(b"Unknown class %s.\n\0" as *const u8 as *const i8, split) });
            (unsafe { exit(1 as i32) });
        }
        i += 1;
    }
    (unsafe { fclose(in_0) });
}
fn main_0(mut _argc: i32, mut _argv: *mut *mut i8) -> i32 {
    (unsafe { printf(b"GENANN example 4.\n\0" as *const u8 as *const i8) });
    (unsafe {
        printf(
            b"Train an ANN on the IRIS dataset using backpropagation.\n\0" as *const u8
                as *const i8,
        )
    });
    (unsafe { srand(time(std::ptr::null_mut::<time_t>()) as u32) });
    load_data();
    let mut ann: *mut genann = unsafe { genann_init(4 as i32, 1, 4, 3) };
    let mut i: i32 = 0;
    let mut j: i32 = 0;
    let mut loops: i32 = 5000;
    (unsafe {
        printf(
            b"Training for %d loops over data.\n\0" as *const u8 as *const i8,
            loops,
        )
    });
    i = 0;
    while i < loops {
        j = 0;
        while j < (unsafe { samples }) {
            (unsafe {
                genann_train(
                    ann,
                    input.offset((j * 4) as isize),
                    class.offset((j * 3) as isize),
                    0.01f64,
                )
            });
            j += 1;
        }
        i += 1;
    }
    let mut correct: i32 = 0;
    j = 0;
    while j < (unsafe { samples }) {
        let mut guess: *const f64 =
            unsafe { genann_run(ann, input.offset((j * 4) as isize)) };
        if (unsafe { *class.offset((j * 3 + 0) as isize) }) == 1.0f64 {
            if (unsafe { *guess.offset(0 as i32 as isize) })
                > (unsafe { *guess.offset(1 as i32 as isize) })
                && (unsafe { *guess.offset(0 as i32 as isize) })
                    > (unsafe { *guess.offset(2 as i32 as isize) })
            {
                correct += 1;
            }
        } else if (unsafe { *class.offset((j * 3 + 1) as isize) }) == 1.0f64 {
            if (unsafe { *guess.offset(1 as i32 as isize) })
                > (unsafe { *guess.offset(0 as i32 as isize) })
                && (unsafe { *guess.offset(1 as i32 as isize) })
                    > (unsafe { *guess.offset(2 as i32 as isize) })
            {
                correct += 1;
            }
        } else if (unsafe { *class.offset((j * 3 + 2) as isize) }) == 1.0f64 {
            if (unsafe { *guess.offset(2 as i32 as isize) })
                > (unsafe { *guess.offset(0 as i32 as isize) })
                && (unsafe { *guess.offset(2 as i32 as isize) })
                    > (unsafe { *guess.offset(1 as i32 as isize) })
            {
                correct += 1;
            }
        } else {
            (unsafe { printf(b"Logic error.\n\0" as *const u8 as *const i8) });
            (unsafe { exit(1 as i32) });
        }
        j += 1;
    }
    (unsafe {
        printf(
            b"%d/%d correct (%0.1f%%).\n\0" as *const u8 as *const i8,
            correct,
            samples,
            correct as f64 / samples as f64 * 100.0f64,
        )
    });
    (unsafe { genann_free(ann) });
    (unsafe { free(input as *mut ()) });
    (unsafe { free(class as *mut ()) });
    return 0;
}
pub fn main() {
    let mut args: Vec<*mut i8> = Vec::new();
    for arg in ::std::env::args() {
        args.push(
            (::std::ffi::CString::new(arg))
                .expect("Failed to convert argument into CString.")
                .into_raw(),
        );
    }
    args.push(::core::ptr::null_mut());
    {
        ::std::process::exit(
            main_0((args.len() - 1) as i32, args.as_mut_ptr() as *mut *mut i8) as i32,
        )
    }
}
